package cc.iotkit.plugins.mattress.cilent;

import cc.iotkit.plugin.core.thing.IThingService;
import cc.iotkit.plugins.mattress.parser.SocketUtil;
import com.gitee.starblues.bootstrap.annotation.AutowiredType;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetSocket;
import lombok.Data;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Objects;

@Slf4j
@Data
public class MattressForwardClient extends AbstractVerticle {

    private MessageConsumer<JsonObject> consumer;
    private NetSocket forwardSocket;
    private Integer port = 5857;
    private String receiveHost = "123.56.196.46";


    @Override
    public void start() throws Exception {
        deployForwardClient();
        initForwardWatch();

    }

    private void initForwardWatch() {
        //注册消息
        EventBus eb = vertx.eventBus();
        consumer = eb.consumer("mattress.forward");
        consumer.handler(message -> {
            log.debug("received a message: " + SocketUtil.bytesToHexString(message.body().getBinary("mattress")));
            NetSocket socket = getForwardSocket();
            if (Objects.nonNull(socket)) {
                socket.write(Buffer.buffer(message.body().getBinary("mattress")));
            } else {
                log.warn("MattressForwardClient disconnected!");
            }
        });
        consumer.completionHandler(res -> {
            if (res.succeeded()) {
                log.info("The handler registration has reached all nodes");
            } else {
                log.error("Registration failed!");
            }
        });
    }

    private void deployForwardClient() {
        if(Objects.nonNull(forwardSocket)){
                forwardSocket.close();
                forwardSocket=null;
        }
        NetClientOptions options = new NetClientOptions()
                .setTcpKeepAlive(true)
                .setReconnectInterval(1000)
                .setReconnectAttempts(-1);
        NetClient client = vertx.createNetClient(options);
        client.connect(port, receiveHost, res -> {
            if (res.succeeded()) {
                log.info("MattressForwardClient Connected!");
                NetSocket socket = res.result();
                if (socket != null) {
                    socket.closeHandler(v -> {
                        log.warn("The socket client has been closed");
                        this.deployForwardClient();
                    });
                    socket.exceptionHandler(v -> {
                        log.error("The socket client has excption" + v.getMessage());
                        this.deployForwardClient();
                    });
                    this.setForwardSocket(socket);
                }
            } else {
                log.error("Failed to connect: " + res.cause().getMessage());
            }
        });
    }

    @Override
    public void stop() throws Exception {
        if (null != forwardSocket) {
            forwardSocket.close();
        }
        if (null != consumer) {
            consumer.unregister();
        }
    }
}
